using System;
using System.Collections.Generic;

namespace MsPartners.Unisys.BizTalkAdapters.AdapterWizard
{
	/// <summary>
	/// Summary description for CSResourceTemplate.
	/// </summary>
	internal class CSResourceTemplate : ResourceTemplate
	{
		/// <summary>
		/// Creates handler extraction code for the transmit adapter properties class
		/// </summary>
		/// <returns></returns>
		override protected string GetCodeTransmitHandlerExtractString(List<AdapterProperty> properties)
		{
			if (properties == null)
				return "";
			string result = "";
			foreach(AdapterProperty ap in properties)
			{
				result += "\t\t\t" + transportType + "TransmitProperties." +
					UncapitalizeFirstLetter(ap.Name) + " = " +
					GetAppropriateExtractFunction(ap.DataType, ap.Name) + ";" + 
					Environment.NewLine;
			}
			return result;
		}

		/// <summary>
		/// Creates handler properties code for the transmit adapter properties class
		/// </summary>
		/// <returns></returns>
		override protected string GetCodeTransmitHandlerPropertiesString(List<AdapterProperty> properties)
		{
			if (properties == null)
				return "";
			string result = "";
			foreach(AdapterProperty ap in properties)
			{
				result += "\t\tpublic static " + ConvertToCsType(ap.DataType) + " " +
					CapitalizeFirstLetter(ap.Name) + 
					" { get { return " + transportType + "TransmitProperties." + UncapitalizeFirstLetter(ap.Name) + "; } }" +
					Environment.NewLine;
			}
			return result;
		}

		/// <summary>
		/// Creates endpoint variables code for the transmit adapter properties class
		/// </summary>
		/// <returns></returns>
		override protected string GetCodeTransmitEndPointMemberString(List<AdapterProperty> properties)
		{
			if (properties == null)
				return "";
			string result = "";
			foreach (AdapterProperty ap in properties)
			{
				result += "\t\tprivate " +
					ConvertToCsType(ap.DataType) +
					" " + UncapitalizeFirstLetter(ap.Name) + ";" + Environment.NewLine;
			}
			return result;
		}

		/// <summary>
		/// Creates endpoint properties code for the transmit adapter properties class
		/// </summary>
		/// <returns></returns>
		override protected string GetCodeTransmitEndPointPropertiesString(List<AdapterProperty> properties)
		{
			if (properties == null)
				return "";
			string result = "";
			foreach (AdapterProperty ap in properties)
			{
				result += "\t\tpublic " + ConvertToCsType(ap.DataType) + " " +
					CapitalizeFirstLetter(ap.Name) + " { get { return this." + UncapitalizeFirstLetter(ap.Name) + "; } }" +
					Environment.NewLine;
			}
			return result;
		}

		/// <summary>
		/// Creates endpoint extraction code for the transmit adapter properties class
		/// </summary>
		/// <returns></returns>
		override protected string GetCodeTransmitEndpointExtractString(List<AdapterProperty> properties)
		{
			if (properties == null)
				return "";
			string result = "";
			foreach (AdapterProperty ap in properties)
			{
				result += "\t\t\tthis." + UncapitalizeFirstLetter(ap.Name) + " = " +
					GetAppropriateExtractFunction(ap.DataType, ap.Name) + ";" +
					Environment.NewLine;
			}
			return result;
		}

		/*
		 * ******************* RECEIVE ************************
		 */

		/// <summary>
		/// Creates handler extraction code for the receive adapter properties class
		/// </summary>
		/// <returns></returns>
		override protected string GetCodeReceiveHandlerExtractString(List<AdapterProperty> properties)
		{
			if (properties == null)
				return "";
			string result = "";
			foreach(AdapterProperty ap in properties)
			{
				result += "\t\t\t" + transportType + "ReceiveProperties." + 
					UncapitalizeFirstLetter(ap.Name) + " = " +
					GetAppropriateExtractFunction(ap.DataType, ap.Name) + ";" + 
					Environment.NewLine;
			}
			return result;
		}

		/// <summary>
		/// Creates handler properties code for the receive adapter properties class
		/// </summary>
		/// <returns></returns>
		override protected string GetCodeReceiveHandlerPropertiesString(List<AdapterProperty> properties)
		{
			if (properties == null)
				return "";
			string result = "";
			foreach (AdapterProperty ap in properties)
			{
				result += "\t\tpublic static " + ConvertToCsType(ap.DataType) + " " +
					CapitalizeFirstLetter(ap.Name) + 
					" { get { return " + transportType + "ReceiveProperties." + UncapitalizeFirstLetter(ap.Name) + "; } }" + 
					Environment.NewLine;
			}
			return result;
		}

		/// <summary>
		/// Creates endpoint member code for the receive adapter properties class
		/// </summary>
		/// <returns></returns>
		override protected string GetCodeReceiveEndPointMemberString(List<AdapterProperty> properties)
		{
			string result = "";
			if (properties != null)
			{
				foreach (AdapterProperty ap in properties)
				{
					result += "\t\tprivate " +
						ConvertToCsType(ap.DataType) +
						" " + UncapitalizeFirstLetter(ap.Name) + ";" +
						Environment.NewLine;
				}
			}
			if (receiveAdapterIsInProcess)//In process adapter needs a polling interval
			{
				result += "\t\tprivate int pollingInterval = 5;";
			}
			if (ReceiveAdapterSupportsReqRsp)
			{
				result += "\t\tprivate int timeout = 90; // in seconds";
			}
			return result;
		}

		/// <summary>
		/// Creates endpoint properties code for the receive adapter properties class
		/// </summary>
		/// <returns></returns>
		override protected string GetCodeReceiveEndPointPropertiesString(List<AdapterProperty> properties)
		{
			string result = "";
			if (properties != null)
			{
				foreach (AdapterProperty ap in properties)
				{
					result += "\t\tpublic " + ConvertToCsType(ap.DataType) + " " +
						CapitalizeFirstLetter(ap.Name) + " { get { return this." + UncapitalizeFirstLetter(ap.Name) + "; } }" +
						Environment.NewLine;
				}
			}
			if (receiveAdapterIsInProcess)//In process adapter needs a polling interval
			{
				result += "\t\tpublic int PollingInterval { get { return pollingInterval; } }";
			}
			if (ReceiveAdapterSupportsReqRsp)
			{
				result += "\t\tpublic int Timeout { get { return timeout; } } // in seconds";
			}
			return result;
		}

		/// <summary>
		/// Creates endpoint extraction code for the receive adapter properties class
		/// </summary>
		/// <returns></returns>
		override protected string GetCodeReceiveEndpointExtractString(List<AdapterProperty> properties)
		{
			string result = "";
			if (properties != null)
			{
				foreach (AdapterProperty ap in properties)
				{
					result += "\t\t\tthis." +
						UncapitalizeFirstLetter(ap.Name) + " = " +
						GetAppropriateExtractFunction(ap.DataType, ap.Name) + ";" +
						Environment.NewLine;
				}
			}
			if (receiveAdapterIsInProcess)//In process adapter needs a polling interval
			{
				result +=
				"\t\t\tint pollingIntervalMultiplier = 1;" + Environment.NewLine + Environment.NewLine +
				"\t\t\tXmlNode nodePollingIntervalUnit = configDOM.SelectSingleNode(\"Config/pollingIntervalUnit\");" + Environment.NewLine +
				"\t\t\tswitch (nodePollingIntervalUnit.InnerText.ToLower())" + Environment.NewLine +
				"\t\t\t{" + Environment.NewLine +
					"\t\t\t\tcase \"milliseconds\":" + Environment.NewLine +
						"\t\t\t\t\tpollingIntervalMultiplier = 1;" + Environment.NewLine +
						"\t\t\t\t\tbreak;" + Environment.NewLine +
					"\t\t\t\tcase \"seconds\":" + Environment.NewLine +
						"\t\t\t\t\tpollingIntervalMultiplier = 1000;" + Environment.NewLine +
						"\t\t\t\t\tbreak;" + Environment.NewLine +
					"\t\t\t\tcase \"minutes\":" + Environment.NewLine +
						"\t\t\t\t\tpollingIntervalMultiplier = 1000 * 60;" + Environment.NewLine +
						"\t\t\t\t\tbreak;" + Environment.NewLine +
				"\t\t\t}" + Environment.NewLine + Environment.NewLine +
				"\t\t\tXmlNode nodePollingInterval = configDOM.SelectSingleNode(\"Config/pollingInterval\");" + Environment.NewLine +
				"\t\t\tint pollingIntervalValue = int.Parse(nodePollingInterval.InnerText);" + Environment.NewLine +
				"\t\t\tthis.pollingInterval = pollingIntervalMultiplier * pollingIntervalValue;" + Environment.NewLine;
			}
			return result;
		}


		/*
		 * ******************* BOTH ************************
		 */
		/// <summary>
		/// Creates validation code for the designtime project
		/// </summary>
		/// <returns></returns>
		override protected string GetCodeDesignTimeValidationString(List<AdapterProperty> properties)
		{
			if (properties == null)
				return "";
			string result = "";
			foreach (AdapterProperty ap in properties)
			{
				result +=
					"\t\t\tstring valueOf" + ap.Name + " = ValidateField(document, \"" + ap.Name + "\");" + Environment.NewLine;
			}
			return result;
		}

		/// <summary>
		/// Creates URI creation code for the designtime project
		/// </summary>
		/// <returns></returns>
		protected override string GetCodeDesignTimeURIString(List<AdapterProperty> properties)
		{
			if (properties == null)
				return "";
			string result = "\t\t\turi.InnerText = \"" + transportType + "://\"";
			foreach (AdapterProperty ap in properties)
			{
				if (ap.PartOfURI)
					result += " + valueOf" + ap.Name + " + \"/\"";
			}
			if (result.EndsWith(" + \"/\""))
			{
				result = result.Remove(result.Length - 6, 6);
			}
			result += ";";
			return result;
		}

		/// <summary>
		/// Creates handler member code for the adapter properties class
		/// </summary>
		/// <returns></returns>
		override protected string GetCodeHandlerMemberString(List<AdapterProperty> properties)
		{
			if (properties == null)
				return "";
			string result = "";
			foreach (AdapterProperty ap in properties)
			{
				result += "\t\tprivate static " +
					ConvertToCsType(ap.DataType) +
					" " + UncapitalizeFirstLetter(ap.Name) + ";" + Environment.NewLine;
			}
			return result;
		}

		/// <summary>
		/// Converts an xsd datatype to a C# datatype
		/// </summary>
		/// <param ap.Name="dataType"></param>
		/// <returns></returns>
		protected string ConvertToCsType(string dataType)
		{
			switch (dataType)
			{
				case "xs:string":
					return "string";
				case "xs:boolean":
					return "bool";
				case "xs:int":
					return "int";
				case "xs:long":
					return "long";
				default:
					return "string";
			}
		}
	}
}
